package com.learn.utils;

import cn.hutool.core.util.IdUtil;
import com.learn.constant.OperatorTokenConstants;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;

import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

/**
 * 操作员-token工具类
 *
 * @author zhouhaofeng
 * @version 2022/10/20 0020
 * @see [相关类/方法]
 * @since [cloud-phone-baseline]
 */
@Slf4j
public class OperatorTokenUtils
{
	private OperatorTokenUtils ()
	{

	}

	@Data
	@Accessors (chain = true)
	public static class TokenClaim
	{
		private String sub;

		private String oriToken;

		private String operatorId;

		private String account;

		private String tenantId;

		private Long exp;

		private String channel;
	}

	/**
	 * 创建操作员Token
	 *
	 * @param tokenClaim       token载荷信息
	 * @param accountSecretKey 账号加密密钥
	 * @param secretKey        jwt密钥
	 * @return jwt
	 */
	public static String createOperatorToken (TokenClaim tokenClaim, String accountSecretKey, String secretKey)
	{

		Map<String, Object> claims = new LinkedHashMap<> ();
		claims.put (OperatorTokenConstants.SUB, tokenClaim.getSub ());
		claims.put (OperatorTokenConstants.ORI_TOKEN, tokenClaim.getOriToken ());
		claims.put (OperatorTokenConstants.OPERATOR_ID, tokenClaim.getOperatorId ());
		claims.put (OperatorTokenConstants.ACCOUNT, AESUtil.encrypt (tokenClaim.getAccount (), accountSecretKey));
		claims.put (OperatorTokenConstants.TENANT_ID, tokenClaim.getTenantId ());
		claims.put (OperatorTokenConstants.EXP, tokenClaim.getExp ());
		claims.put (OperatorTokenConstants.CHANNEL, tokenClaim.getChannel ());
		return Jwts.builder ().setClaims (claims).signWith (SignatureAlgorithm.HS512,
				Base64Utils.encodeToString (secretKey.getBytes (StandardCharsets.UTF_8))).compact ();
	}

	/**
	 * 获取原始Token
	 *
	 * @return 原始Token字符串
	 */
	public static String getOriToken ()
	{
		return IdUtil.fastSimpleUUID ().toUpperCase (Locale.US);
	}
}
